package com.pug.zixun.config.interceptor.login;

import com.pug.zixun.commons.anno.IgnoreToken;
import com.pug.zixun.commons.enums.AdminUserResultEnum;
import com.pug.zixun.commons.ex.PugValidatorException;
import com.pug.zixun.commons.utils.fn.asserts.Vsserts;
import com.pug.zixun.config.redis.AdminRedisKeyManager;
import com.pug.zixun.local.UserThreadLocal;
import com.pug.zixun.pojo.AdminUser;
import com.pug.zixun.service.adminuser.IAdminUserService;
import com.pug.zixun.service.jwt.JwtService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @author 飞哥
 * @Title: 学相伴出品
 * @Description: 飞哥B站地址：https://space.bilibili.com/490711252
 * 记得关注和三连哦！
 * @Description: 我们有一个学习网站：https://www.kuangstudy.com
 * @date 2022/5/16$ 22:27$
 */
@Component
@Slf4j
public class PassportLoginInterceptor implements HandlerInterceptor, AdminRedisKeyManager {

    @Autowired
    private JwtService jwtService;
    @Autowired
    private IAdminUserService adminUserService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //String xmlhttp = request.getHeader("X-Requested-With");//XMLHttpRequest
        //boolean isAjax = xmlhttp.equalsIgnoreCase("XMLHttpRequest");
        // handler从object对象转换成具体的目标对象HandlerMethod
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 获取执行的方法
        Method method = handlerMethod.getMethod();
        if (method.getAnnotation(IgnoreToken.class) != null ||
                handlerMethod.getBeanType().getAnnotation(IgnoreToken.class) != null) {
            return true;
        }
        // 获取用户请求的token
        String token = jwtService.getToken(request);
        // 如果token没有传递，直接走统一异常处理 + 统一返回(内部自动帮你把数据通过jackson转换成json返回)
        Vsserts.isEmptyEx(token, AdminUserResultEnum.TOKEN_NOT_FOUND);
        // 获取请求头的用户id
        String tokenUserId = jwtService.getTokenUserId(request);
        // 校验token是否合法
        boolean refreshTokenRedis = jwtService.refreshTokenRedis(token,tokenUserId,response);
        Vsserts.isFalseEx(refreshTokenRedis, AdminUserResultEnum.TOKEN_ERROR);
        // 解析token,获取用户id
        Vsserts.isNullEx(tokenUserId, AdminUserResultEnum.USER_NULL_ERROR);
        // 根据用户查询用户信息，实时性 db 0.007
        AdminUser adminUser = adminUserService.getById(Long.parseLong(tokenUserId));
        Vsserts.isNullEx(adminUser, AdminUserResultEnum.USER_NULL_ERROR);
        // 拉黑处理
        if (adminUser.getStatus() != null && adminUser.getStatus().equals(0)) {
            throw new PugValidatorException(AdminUserResultEnum.USER_FORBIDDEN_ERROR);
        }
        // 删除处理
        if (adminUser.getIsdelete() != null && adminUser.getIsdelete().equals(1)) {
            throw new PugValidatorException(AdminUserResultEnum.USER_FORBIDDEN_ERROR);
        }
        // 把用户信息放入到UserThreadLocal
        UserThreadLocal.put(adminUser);

        return true;
    }



    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        UserThreadLocal.remove();
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserThreadLocal.remove();
    }
}
